home *** CD-ROM | disk | FTP | other *** search
- (* TURBO PASCAL 4.0 version of MSBPCT *)
- (* *)
- (* Author: Helmut Waelder (ZRWA001 at DTUZDV1.BITNET) *)
- (* Zentrum fuer Datenverarbeitung *)
- (* Brunnenstr. 27 *)
- (* D-7400 Tuebingen *)
- (* *)
- (* Version 1.1 of 87/11/22 - modified to check for *)
- (* corrupted input (optional) and to allow *)
- (* output file name overriding *)
- (* Gisbert W.Selke (RECK@DBNUAMA1.BITNET) *)
- (* Wissenschaftliches Institut der Ortskrankenkassen*)
- (* Kortrijker Strasse 1 *)
- (* D-5300 Bonn 1 *)
- (* West Germany *)
- (* Version 1.2 of 88/02/10 - modified for Turbo Pascal 4.0 *)
- (* *)
- (* Decodes the mskermit.boo file about three times as fast *)
- (* as the C version (if checking is not ON) *)
-
- (*$S-*) (* Stack checking off *)
- (*$R-*) (* Range checking off *)
- (*$B-*) (* Boolean complete evaluation off *)
- (*$I+*) (* I/O checking on *)
- (*$N-*) (* No numeric coprocessor *)
- (*$M 65500,16384,16384*) (* Reduce maximum heap *)
-
- program msbpct;
-
- uses crt;
-
- const repbyte : byte = 78; (* ord('tilde') - ord('0') *)
- zerobyte : byte = 48;
- zerochar = '0';
- smallo = 'o';
- tilde = '~';
- nullchar : char = #0;
- maxlinlength = 76;
- bufsize = 31500;
- defaultinname = 'MSTIBM.BOO';
- defaultoutname = 'MSTIBM.EXE';
- defaultext = '.BOO';
-
- type buftype = array (.1..bufsize.) of byte;
-
- var a, b, c, d : byte;
- i, index, linno, linlength : integer;
- isend, ok, relax : boolean;
- infilename, outfilename, originalname : string(.63.);
- (* maximum path length in DOS *)
- line : string(.132.);
- inbuffer, outbuffer : buftype;
- infile, outfile : text;
-
- function getbyte(mode : integer) : byte;
- (* get one proper character from input stream and decode it *)
- var c : char;
- ok : boolean;
-
- procedure errmsg(errmode : integer);
- (* output various error messages *)
- begin
- case errmode of
- 0 : writeln('Improper character #',ord(c),
- ' at line/column ',linno,'/',index);
- 1 : writeln('Improper null repeat count #',ord(c),
- ' at line/column ',linno,'/',index);
- 2 : writeln('Input line #',linno,' too long');
- end;
- end; (* errmsg *)
-
- begin (* getbyte *)
- repeat (* until proper character or eof *)
- c := zerochar;
- inc(index);
- while (index > linlength) and (not isend) do
- begin (* get new input line *)
- inc(linno);
- if lo(linno) = 0 then write(chr(13),'Line ',linno);
- isend := eof(infile);
- if not isend then readln(infile,line);
- linlength := length(line);
- if linlength > maxlinlength then errmsg(2);
- index := 1;
- end; (* get new input line *)
- if not isend then c := line(.index.);
- ok := isend or relax;
- if not ok then
- begin (* be suspicious *)
- if c in (.zerochar..smallo.) then ok := true (* vanilla character *)
- else (* depending on context *)
- begin (* be suspicious *)
- if c <> ' ' then
- case mode of
- 0 : errmsg(0); (* within ordinary chunk *)
- 1 : if c = tilde then ok := true (* first byte of chunk... *)
- else errmsg(0); (* ... may also be tilde *)
- 2 : if c in (.smallo..tilde.) then ok := true (* repeat count *)
- else errmsg(1);
- end; (* depending on context *)
- end;
- end; (* be suspicious *)
- until ok; (* until proper character or eof *)
- getbyte := ord(c) - zerobyte;
- end; (* getbyte *)
-
- procedure prepare;
- (* get input and output file names; open files *)
- var ch : char;
- option : string(.10.);
- ctemp : string(.63.);
- begin
- if paramcount > 3 then
- Begin (* argument number error *)
- writeln('Wrong number of parameters.');
- writeln('Usage: MSBPCT (<input file name> (<output file name>)) (/C)');
- halt(1);
- end; (* argument number error *)
- if paramcount >= 1 then infilename := paramstr(1)
- else infilename := defaultinname;
- if pos('.',infilename) = 0 then infilename := infilename + defaultext;
- assign(infile,infilename);
- settextbuf(infile,inbuffer);
- (*$I-*) reset(infile); (*$I+*)
- if IOResult <> 0 then
- begin
- writeln(infilename,' not found');
- halt(1);
- end;
- readln(infile,originalname);
- while ((length(originalname) > 0) and (originalname(.1.) = ' ')) do
- delete(originalname,1,1);
- if pos(' ',originalname) > 0 then
- delete(originalname,pos(' ',originalname),999);
- if length(originalname) = 0 then
- begin
- writeln('Original file name missing - replaced by ',defaultoutname);
- originalname := defaultoutname;
- end;
- outfilename := originalname;
- option := '';
- if paramcount >= 2 then
- begin (* more parameters *)
- if paramcount > 2 then
- begin (* still more parameters *)
- outfilename := paramstr(2);
- option := copy(paramstr(3),1,10);
- end (* still more parameters *)
- else
- begin (* two parameters *)
- ctemp := paramstr(2);
- if ctemp(.1.) = '/' then option := copy(ctemp,1,10)
- else outfilename := ctemp;
- end; (* two parameters *)
- end; (* more parameters *)
- relax := true;
- if option <> '' then
- begin
- if (option = '/C') or (option = '/c') then relax := false
- else writeln('Only option available is [/C[')
- end;
- assign(outfile,outfilename);
- settextbuf(outfile,outbuffer);
- (*$I-*) reset(outfile); (*$I+*)
- if IOResult = 0 then
- begin (* overwrite existing file? *)
- write('Output file ',outfilename,
- ' already exists. Continue (y/n)? ');
- repeat
- ch := readkey;
- ch := upcase(ch);
- until ch in (.'N','0','J','Y','1'.);
- writeln;
- if ch in (.'N','0'.) then halt(1);
- end; (* overwrite existing file? *)
- (*$I-*) rewrite(outfile); (*$I+*)
- if IOResult<>0 then
- begin
- writeln('Couldn''t open ',outfilename);
- halt(1);
- end;
- checkbreak := false;
- end; (* prepare *)
-
- Begin (* main *)
- writeln('MSBPCT 1.2');
- prepare;
- writeln('Decoding ',infilename,', creating ',outfilename);
- if outfilename <> originalname then write(' (Original name was ',
- originalname,')');
- if not relax then write(' (checking integrity)');
- writeln;
- isend := false;
- linlength := 0;
- index := succ(maxlinlength);
- linno := 1;
- while not isend do
- begin (* get all chunks *)
- a := getbyte(1);
- if a = repbyte then
- begin (* null repeating *)
- b := getbyte(2);
- for i:=1 to b do write(outfile,nullchar);
- end (* null repeating *)
- else
- begin (* ordinary chunk *)
- b := getbyte(0);
- c := getbyte(0);
- d := getbyte(0);
- write(outfile,chr((a shl 2) or (b shr 4)));
- write(outfile,chr((b shl 4) or (c shr 2)));
- write(outfile,chr((c shl 6) or d));
- end; (* ordinary chunk *)
- end; (* get all chunks *)
- (* write(outfile,#26); *) (* there is no need to append a ctrl-z *)
- flush(outfile);
- close(infile);
- close(outfile);
- writeln(chr(13),linno,' lines read.');
- end. (* main *)
-